﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Globalization;
using System.IO;
using System.Management;
using AlarmClock.LxzhClass;

namespace AlarmClock
{
    public partial class FrmClock : FrmAutoBerthForm
    {
        private ToolStripMenuItem toolStripMenuItem;
        private ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
        private static String DB_STRING = "C:\\ProgramData\\Microsoft\\AlarmClock";
        private DataBase database;
        private List<Alarm> alarmList = null;
        private int alarmCount;
        private String nextAlarm = "";
        private MediaPlayer mediaPlayer;
        private FrmCalendarTool calenderTool;
        private bool isCalenderShow = false;
        private bool isContextMenuShow = false;

        public FrmClock()
        {
            InitializeComponent();
            timeTimer.Enabled = true;
        }
        //无边窗体的拖动
        [DllImport("user32.dll")]  //需添加using System.Runtime.InteropServices
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_MOVE = 0xF010;
        public const int HTCAPTION = 0x0002;

        private void Clock_MouseDown(object sender, MouseEventArgs e)
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
            if (e.Button == MouseButtons.Right)
            {
                if (calenderTool != null)
                {
                    日历ToolStripMenuItem.Visible = false;
                    if (!calenderTool.isAlive())
                    {
                        日历ToolStripMenuItem.Visible = true;
                    }
                }
            }
        }

        private void timeTimer_Tick(object sender, EventArgs e)
        {
            DateTime now = DateTime.Now;
            this.lblTime.Text = now.ToLongTimeString();
            int n = (int)now.DayOfWeek;
            string[] weekDays = { "星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
            this.lblWeek.Text = now.Year + "/" + now.Month + " " + weekDays[n];
            this.lblDay.Text = now.Day + "";
            this.lblLoveTime.Text = getChineseDate(now);

            if (calenderTool != null)
            {
                if (calenderTool.isAlive())
                {
                    isCalenderShow = true;
                }
                else
                {
                    isCalenderShow = false;
                }
            }
        }

        private void timMouseState_Tick(object sender, EventArgs e)
        {
            if (!isCalenderShow && !isContextMenuShow)
            {
                timCheckMouseState.Start();
            }
            else
            {
                timCheckMouseState.Stop();
            }
        }

        private void Clock_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists(DB_STRING)) Directory.CreateDirectory(DB_STRING);
            checkSystemDll();
            database = new DataBase(DB_STRING + "\\AlarmClock.db", "19920602120");
            database.createTable(1);
            database.createTable(2);
            database.createTable(3);

            timeTimer_Tick(sender, e);
            toolStripMenuItem = toolStripMenuItem5;
            Screen screen = Screen.PrimaryScreen;
            this.Left = screen.Bounds.Width - this.Width;
            this.Top = 0;
            this.Region = null;
            SetWindowRegion();
            setStart(1);
            timNextAlarm_Tick(sender, e);
            timAlam_Tick(sender, e);
            timMouseState_Tick(sender, e);
        }

        private void Clock_LocationChanged(object sender, EventArgs e)
        {
            if (calenderTool != null)
            {
                calenderTool.setLocation(this.Left, this.Bottom);
            }
        }

        private void tToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmSetTime fr = new FrmSetTime();
            fr.database = database;
            fr.Show();
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            toolStripMenuItem.Checked = false;
            this.Opacity = 0.2;
            toolStripMenuItem2.Checked = true;
            toolStripMenuItem = toolStripMenuItem2;
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            toolStripMenuItem.Checked = false;
            this.Opacity = 0.4;
            toolStripMenuItem3.Checked = true;
            toolStripMenuItem = toolStripMenuItem3;
        }

        private void toolStripMenuItem4_Click(object sender, EventArgs e)
        {
            toolStripMenuItem.Checked = false;
            this.Opacity = 0.6;
            toolStripMenuItem4.Checked = true;
            toolStripMenuItem = toolStripMenuItem4;
        }

        private void toolStripMenuItem5_Click(object sender, EventArgs e)
        {
            toolStripMenuItem.Checked = false;
            this.Opacity = 0.8;
            toolStripMenuItem5.Checked = true;
            toolStripMenuItem = toolStripMenuItem5;
        }

        private void toolStripMenuItem6_Click(object sender, EventArgs e)
        {
            toolStripMenuItem.Checked = false;
            this.Opacity = 1;
            toolStripMenuItem6.Checked = true;
            toolStripMenuItem = toolStripMenuItem6;
        }

        private void 开机启动ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (开机启动ToolStripMenuItem.Checked == true)
            {
                开机启动ToolStripMenuItem.Checked = false;
                setStart(0);
            }
            else
            {
                开机启动ToolStripMenuItem.Checked = true;
                setStart(1);
            }
        }

        private void 更改铃声库ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmAddMusic addMusic = new FrmAddMusic();
            addMusic.database = database;
            addMusic.Show();
        }

        private void 日历ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Screen screen = Screen.PrimaryScreen;
            int width = screen.Bounds.Width;
            int height = screen.Bounds.Height;
            int pre_x = this.Left;
            int pre_y = this.Top;
            int to_x = 0, to_y = 0;
            if (pre_x < 0)
                to_x = 0;
            else if (pre_x > width - this.Width)
                to_x = width - this.Width;
            else to_x = this.Left;
            if (pre_y < 0)
                to_y = 0;
            else if (pre_y > height - 2 * this.Height)
                to_y = height - 2 * this.Height;
            else to_y = this.Top;
            changeLocation(pre_x, to_x, pre_y, to_y);
            calenderTool = new FrmCalendarTool(to_x, to_y + this.Height);
            calenderTool.Show();
            timCheckMouseState.Stop();
        }

        private void 倒计时ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmCountDown countDown = new FrmCountDown();
            countDown.database = database;
            countDown.Show();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //绘制圆角
        public void SetWindowRegion()
        {
            System.Drawing.Drawing2D.GraphicsPath FormPath = new System.Drawing.Drawing2D.GraphicsPath();
            Rectangle rect = new Rectangle(0, 2, this.Width, this.Height - 2);//this.Left-10,this.Top-10,this.Width-10,this.Height-10);                 
            FormPath = GetRoundedRectPath(rect, 30);
            this.Region = new Region(FormPath);
        }

        private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            int diameter = radius;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
            GraphicsPath path = new GraphicsPath();
            //   左上角   
            path.AddArc(arcRect, 180, 90);
            //   右上角   
            arcRect.X = rect.Right - diameter;
            path.AddArc(arcRect, 270, 90);
            //   右下角   
            arcRect.Y = rect.Bottom - diameter;
            path.AddArc(arcRect, 0, 90);
            //   左下角   
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();
            return path;
        }

        public void changeLocation(int pre_x, int to_x, int pre_y, int to_y)
        {
            int totalTime = (Math.Abs(to_x - pre_x) > Math.Abs(to_y - pre_y) ? Math.Abs(to_x - pre_x) : Math.Abs(to_y - pre_y));

            for (int i = 0; i < totalTime; i++)
            {
                pre_x = this.Left;
                pre_y = this.Top;
                if (pre_x == to_x && pre_y == to_y) return;
                Thread.Sleep((totalTime - i) / 300);
                if (pre_x > to_x)
                    this.Left -= 1;
                else if (pre_x < to_x)
                    this.Left += 1;
                if (pre_y > to_y)
                    this.Top -= 1;
                else if (pre_y < to_y)
                    this.Top += 1;
            }
        }

        public void setStart(int state)
        {
            //
            //state=1,开机启动
            //state=0,禁止开机启动
            //
            //获取程序执行路径...
            string starupPath = Application.ExecutablePath;
            //class Micosoft.Win32.RegistryKey. 表示Window注册表中项级节点,此类是注册表装.
            RegistryKey loca = Registry.LocalMachine;
            RegistryKey key = loca.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
            object obj = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", Application.ProductName, null);
            try
            {
                if (state == 1 && obj == null)
                {
                    //SetValue:存储值的名称
                    key.SetValue(Application.ProductName, starupPath);
                    //Thread.Sleep(1000);                  
                }
                else if (state == 0 && obj != null)
                {
                    //SetValue:存储值的名称
                    key.DeleteValue(Application.ProductName);
                }
                loca.Close();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public string getChineseDate(DateTime date)
        {
            int lYear = chineseDate.GetYear(date);
            int lMonth = chineseDate.GetMonth(date);
            int lDay = chineseDate.GetDayOfMonth(date);

            String dateStr = "";

            /** GetLeapMonth(int year)方法返回一个1到13之间的数字， 
             * 比如：1、该年阴历2月有闰月，则返回3 
             * 如果：2、该年阴历8月有闰月，则返回9 
             * GetMonth(DateTime dateTime)返回是当前月份，忽略是否闰月 
             * 比如：1、该年阴历2月有闰月，2月返回2，闰2月返回3 
             * 如果：2、该年阴历8月有闰月，8月返回8，闰8月返回9 
             */
            int leapMonth = chineseDate.GetLeapMonth(lYear);//获取第几个月是闰月,等于0表示本年无闰月  

            //如果今年有闰月  
            if (leapMonth > 0)
            {
                //闰月数等于当前月份  
                if (lMonth == leapMonth)
                {
                    dateStr = String.Format("阴历{0}年\n闰{1}月{2}日", lYear, lMonth - 1, lDay);
                    //Console.WriteLine("今年的阴历日期：{0}年闰{1}月{2}日。", lYear, lMonth - 1, lDay);
                }
                else if (lMonth > leapMonth)//  
                {
                    dateStr = String.Format("阴历{0}年\n{1}月{2}日", lYear, lMonth - 1, lDay);
                    //Console.WriteLine("今年的阴历日期：{0}年{1}月{2}日。", lYear, lMonth - 1, lDay);
                }
                else
                {
                    dateStr = String.Format("阴历{0}年\n{1}月{2}日", lYear, lMonth, lDay);
                    //Console.WriteLine("今年的阴历日期：{0}年{1}月{2}日。", lYear, lMonth, lDay);
                }
            }
            else
            {
                dateStr = String.Format("阴历{0}年\n{1}月{2}日", lYear, lMonth, lDay);
                //Console.WriteLine("今年的阴历日期：{0}年{1}月{2}日。", lYear, lMonth, lDay);
            }
            return dateStr;
        }

        private void timNextAlarm_Tick(object sender, EventArgs e)
        {
            alarmList = database.getAlarmList();
            alarmCount = alarmList.Count();
            Alarm alarm = new Alarm();
            DateTime nowTime = DateTime.Now;
            DateTime alarmTime;
            int i = 0;
            for (; i < alarmCount; i++)
            {
                alarm = alarmList.ElementAt(i);
                alarmTime = alarm.date;
                alarmTime = alarmTime.AddHours(Convert.ToInt16(alarm.time.Substring(0, 2)));
                alarmTime = alarmTime.AddMinutes(Convert.ToInt16(alarm.time.Substring(3, 2)));
                alarmTime = alarmTime.AddSeconds(0);
                if (alarmTime > nowTime)
                {
                    nextAlarm = alarmTime.ToShortDateString() + " " + alarmTime.ToShortTimeString();
                    lblAlarm.Left = 30;
                    lblnextAlarm.Left = 60;
                    break;
                }
            }
            if (i == alarmCount)
            {
                lblnextAlarm.Text = "00:00:00";
                lblAlarm.Left = 50;
                lblnextAlarm.Left = 80;
            }
            else lblnextAlarm.Text = nextAlarm;
        }

        private void timAlam_Tick(object sender, EventArgs e)
        {
            DateTime nowTime = DateTime.Now;
            DateTime alarmTime;
            Alarm alarm = new Alarm();
            int i;
            for (i = 0; i < alarmCount; i++)
            {
                alarm = alarmList.ElementAt(i);
                alarmTime = alarm.date;
                alarmTime = alarmTime.AddHours(Convert.ToInt16(alarm.time.Substring(0, 2)));
                alarmTime = alarmTime.AddMinutes(Convert.ToInt16(alarm.time.Substring(3, 2)));
                alarmTime = alarmTime.AddSeconds(0);
                if ((alarmTime.ToShortDateString() + " " + alarmTime.ToShortTimeString()) == (nowTime.ToShortDateString() + " " + nowTime.ToShortTimeString()) && (nowTime - alarmTime).TotalSeconds < 1)
                {
                    if (mediaPlayer != null) mediaPlayer.close();
                    mediaPlayer = new MediaPlayer(alarm.musicId, database);
                    mediaPlayer.Show();
                    break;
                }
            }
        }

        private void contextMenuStrip_Opened(object sender, EventArgs e)
        {
            isContextMenuShow = true;
        }

        private void contextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
        {
            isContextMenuShow = false;
        }

        private void checkSystemDll()
        {
            if (!File.Exists("Alarm.dat"))
            {
                int osBit = GetOSBit();
                String dllName = "System.Data.SQLite.dll";
                if (osBit == 64)
                {
                    File.Delete(dllName);
                    try
                    {
                        unZipFile("System.Data.SQLite.zip");
                        File.Delete("System.Data.SQLite.zip");
                    }
                    catch (Exception)
                    {
                    }
                }
                File.Create("Alarm.dat");
            }
        }
        /// 获取操作系统位数（x32/64）
        /// </summary>
        /// <returns>int</returns>
        private int GetOSBit()
        {
            try
            {
                string addressWidth = String.Empty;
                ConnectionOptions mConnOption = new ConnectionOptions();
                ManagementScope mMs = new ManagementScope(@"\\localhost", mConnOption);
                ObjectQuery mQuery = new ObjectQuery("select AddressWidth from Win32_Processor");
                ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(mMs, mQuery);
                ManagementObjectCollection mObjectCollection = mSearcher.Get();
                foreach (ManagementObject mObject in mObjectCollection)
                {
                    addressWidth = mObject["AddressWidth"].ToString();
                }
                return Int32.Parse(addressWidth);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return 32;
            }
        }

        private void unZipFile(String path)
        {
            ZipUtil zipUtil = new ZipUtil();
            zipUtil.UnZipFile(path);
        }
    }
}
